package com.ftwj.demo.base.util;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import com.ftwj.demo.base.cache.CustomCache;
import com.ftwj.demo.base.cache.impl.EhcacheCache;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

public class CacheUtil {
	
	private static final Log log = LogFactory.get(CacheUtil.class);

	/**
	 * 
	 * <p>Title: getStackTraceElement</p>  
	 * <p>Description: 获取方法调用时的堆栈跟踪信息</p>  
	 * @return 
	 * @author WangSLi
	 * @date 2020年5月2日  
	 * @version 1.0
	 */
	public static StackTraceElement[] getStackTrace() {
		return Thread.currentThread().getStackTrace();
	}
	
	/**
	 * 
	 * <p>Title: getActualTypeArgument</p>  
	 * <p>Description: 获取泛型类Class对象</p>  
	 * @param clazz
	 * @return 
	 * @author WangSLi
	 * @date 2020年5月4日  
	 * @version 1.0
	 */
	public static Class<?> getActualType(Class<?> cls) {
		Type genericSuperclass = cls.getGenericSuperclass();
		Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments();
		return (Class<?>) actualTypeArguments[0];
	}
	
	/**
	 * 
	 * <p>Title: getCache</p>  
	 * <p>Description: 获取对应的缓存对象</p>  
	 * @return 
	 * @author WangSLi
	 * @date 2020年5月4日  
	 * @version 1.0
	 * @throws Exception 
	 */
	public static CustomCache getCache() {
		StackTraceElement[] temp=Thread.currentThread().getStackTrace();
		//此处取{3}，因为：CacheKeyGenerateUtil->BaseJdbcTemplate->xxxDao 追踪方法调用堆栈信息到xxxDao
		StackTraceElement element=(StackTraceElement) temp[3]; 
		String name = element.getClassName();
		log.debug("CACHE_NAME:{}",name);
		return new EhcacheCache(name);
	}
	public static CustomCache getCache(final Class<? extends CustomCache> cls) {
		StackTraceElement[] temp=Thread.currentThread().getStackTrace();
		//此处取{3}，因为：CacheKeyGenerateUtil->BaseJdbcTemplate->xxxDao 追踪方法调用堆栈信息到xxxDao
		StackTraceElement element=(StackTraceElement) temp[3]; 
		String name = element.getClassName();
		log.debug("CACHE_NAME:{}",name);
		return ReflectUtil.newInstance(cls,name);
	}
	
	/**
	 * 
	 * <p>Title: getKey</p>  
	 * <p>Description: 生成缓存键</p>  
	 * @param sql SQL语句
	 * @param res 返回值类型
	 * @param objects 参数
	 * @return 
	 * @author WangSLi
	 * @date 2020年5月4日  
	 * @version 1.0
	 */
	public static String getKey(String sql,Object...objects) {
		StackTraceElement[] temp=Thread.currentThread().getStackTrace();
		StackTraceElement element=(StackTraceElement)temp[3]; 
		StringBuilder builder=new StringBuilder(element.getClassName()+"."+ element.getMethodName());
		builder.append("[").append(sql).append("][");
		String params = CacheKeyGenerator.generate(objects);
		String key=builder.append(params).append("]").toString();
		log.debug("MD5(KEY_NAME:{})",key);
		return MD5.encode(key);
	}
	
}
